package com.tidc.seaserverservice.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tidc.seaservermapper.dao.TaskDao;
import com.tidc.seaservermapper.dao.UserTaskDao;
import com.tidc.seaservermodel.dto.HistogramDto;
import com.tidc.seaservermodel.entity.*;
import com.tidc.seaservermodel.exception.TidcAuthorityException;
import com.tidc.seaservermodel.exception.TidcBadParent;
import com.tidc.seaservermodel.util.SpringUtil;
import com.tidc.seaserverservice.service.SupervisorTaskService;
import com.tidc.seaserverservice.util.RabbitUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author ：冯涛滔
 * @date ：Created in 2020/9/12 16:13
 * @description：
 * @modified By：
 * @version:
 */
@Service
@Slf4j
public class SupervisorTaskServiceImpl implements SupervisorTaskService {
    @Resource
    private TaskDao taskDao;
    @Resource
    private UserTaskDao userTaskDao;
    @Resource
    private RabbitUtil rabbitUtil;
    @Resource
    private ObjectMapper objectMapper;
    @Transactional(rollbackFor = SQLException.class)
    @Override
    public Fres<Integer> addTask(Task task, Authentication authentication) throws SQLException{
        task.setUserId(Integer.valueOf(authentication.getName()));
        taskDao.insert(task);

        return Fres.Success();
    }

    @Override
    public Fres<Map<Object, Object>> getTaskAll(String query,int pageSize, int pageNum,Authentication authentication) throws TidcAuthorityException, TidcBadParent {
        int checkId = Integer.parseInt(authentication.getName());
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
//        for (GrantedAuthority authority : authorities) {
//            if(authority.getAuthority().equals("ROLE_secondary")){
//                User user = userDao.queryById(Integer.valueOf(authentication.getName()));
//                checkId = user.getSuperiorUserId();
//            }
//        }
        int taskCount = taskDao.getUserTaskCount(query,checkId);
        Map<Object, Object> map = SpringUtil.pagingPrepare(pageSize, pageNum, taskCount);
        List<Task> tasks = taskDao.queryAllByLimit(query,(pageNum - 1) * pageSize, pageSize, checkId);
        map.put("list", tasks);
        return Fres.Success(map, "查询成功");
    }

    @Override
    public Fres<Map<Object, Object>> getAuditList(int id, int pageSize, int pageNum, Authentication authentication) throws TidcBadParent {
        int count = userTaskDao.getChildAuditListCount(id);
        Map<Object, Object> map = SpringUtil.pagingPrepare(pageSize, pageNum, count);
        List<Task> childAuditList = userTaskDao.getChildAuditList(id, (pageNum - 1) * pageSize, pageSize);
        map.put("list",childAuditList);
        return Fres.Success(map,"成功");
    }

    @Override
    public Fres<List<HistogramDto>> getWithinTaskInfo(int day, int id, Authentication authentication) {
        List<HistogramDto> withinTaskInfo = userTaskDao.getWithinTaskInfo(id, Integer.parseInt(authentication.getName()), day);
        return Fres.Success(withinTaskInfo,"成功");
    }
    @Transactional(rollbackFor = {TidcAuthorityException.class,SQLException.class})
    @Override
    public Fres<String> finishSecondaryTask(UserTask userTask, Authentication authentication) throws TidcAuthorityException, SQLException, JsonProcessingException {
        UserTask ut = userTaskDao.queryById(userTask.getId());
        Task task = taskDao.queryById(ut.getTaskId());
        if(task.getAccomplishType()!=1||!task.getUserId().equals(Integer.parseInt(authentication.getName()))){
            log.error("用户 {} 试图完成任务 userTask {}被阻止",authentication.getName(),userTask);
            throw new TidcAuthorityException("这个任务你无权限完结");
        }
        userTaskDao.finishTask(userTask.getId(),userTask.getIsAccomplish(),null);
//      如果是一次性任务完成了设置成删除
        if(task.getTypeClassify() == 2){
            task.setIsDelete(1);
            taskDao.update(task);
        }


        Email email = null;
        RabbitMessageLog experienceLog = null;
        RabbitMessageLog emailLog = null;
        if (userTask.getIsAccomplish() == 1) {
            email = Email.systemAccomplishTaskEmail("你提交的审批已被通过","你提交的审批任务:"+task.getName()+"已被通过",ut.getUserId());
            emailLog = RabbitMessageLog.sendEmail(objectMapper.writeValueAsString(email));
            experienceLog = RabbitMessageLog.addExperience(objectMapper.writeValueAsString(userTask));
        } else {
            email = Email.systemAccomplishTaskEmail("你提交的审批已被否决","你提交的审批任务:"+task.getName()+"已被否决",ut.getUserId());
            emailLog = RabbitMessageLog.sendEmail(objectMapper.writeValueAsString(email));
            experienceLog = RabbitMessageLog.punishmentExperience(objectMapper.writeValueAsString(userTask));
        }
        rabbitUtil.sendMQ(emailLog);
        rabbitUtil.sendMQ(experienceLog);
        return Fres.Success();
    }
    @Transactional(rollbackFor = {TidcAuthorityException.class,SQLException.class})
    @Override
    public Fres<String> alterTask(Task task, Authentication authentication) throws TidcAuthorityException, SQLException {
        Task checkTask = taskDao.queryById(Integer.valueOf(authentication.getName()));
        if(!checkTask.getUserId().equals(Integer.valueOf(authentication.getName()))){
            log.error("用户{} 在试图修改不属于他的task{}",authentication.getName(),task);
            throw new TidcAuthorityException("无权访问他人的资源");
        }
        int count = taskDao.update(task);
        if (count<0){
            log.error("用户 {} 在修改任务时 Task {}时 sql没有执行成功",authentication.getName(),task);
            throw new SQLException("执行sql失败");
        }
        return Fres.Success();
    }


}
